// students.js
// 数据操作文件模块
// 职责：操作文件中的数据，只处理数据，不关心业务

var fs = require("fs");

var dbPath = "./db.json";

// 1.获取所有学生数据
/* 
  callback 中的参数
    第一个参数是 error
        成功是  null
        失败是 错误对象 error
    第二个参数是 结果
        成功是 数组
        失败是 underfine 
*/
exports.findAll = function (callback) {
  fs.readFile(dbPath, "utf8", function (error, data) {
    if (error) {
      callback(error);
    }
    //   成功 则为 null  并获取结果  这里将结果(db.json)里面的 students 转化成对象
    callback(null, JSON.parse(data).students);
  });
};

// 2.保存 添加学生信息
/* 
 S1.先将dbPath数据文件读取过来，S2.转换成JSON对象，S3.然后将用户保存数据  (用户保存的数据是
放在newStudent中的) S4. 添加到(push)dbPath文件中，再转为字符串(通过stringify 方法)
再通过 文件写入的方式，将新的数据保存到dbPath文件中
 */
exports.save = function (newStudent, callback) {
  fs.readFile(dbPath, "utf8", function (error, data) {
    if (error) {
      callback(error);
    }
    //   将db里面的学生数据 转换成JSON对象
    var students = JSON.parse(data).students;

    // 处理ID唯一性，不重复   在原有的最后一个id上加1，确保不重复
    // students[students.length - 1] 数据文件中表示最后一个id
    // 得到的 students[students.length - 1] 是一个字符串
    newStudent.id = parseInt(students[students.length - 1].id) + 1;

    //   将新的学生数据  放到 旧的学生数据中
    students.push(newStudent);
    // 把对象数据转换成字符串 通过 stringify  因为db.json中是以字符串的形式存储的
    var fileData = JSON.stringify({
      students: students,
    });
    // writeFile 内的三个参数
    fs.writeFile(dbPath, fileData, function (error, data) {
      if (error) {
        return callback(error);
      }
      callback(null);
    });
  });
};

// 3.更改学生信息
// newStudent  是专门用来表示  存放的新数据，也就是提交的数据
exports.updateById = function (newStudent, callback) {
  fs.readFile(dbPath, "utf8", function (error, data) {
    if (error) {
      callback(error);
    }
    var students = JSON.parse(data).students;

    //   这里要将  要更改的学生id 转换成 数字型，不然在db.json中以字符串的形式存储
    newStudent.id = parseInt(newStudent.id);

    //   判断  更改学生的 id   通过id  获取学生的数据
    /*  find数组方法，需要接收一个函数作为参数，当某个遍历项 
      item.id === students.id条件的时候，find会终止遍历，同时返回遍历值 */
    var stu = students.find(function (item) {
      // item.id = parseInt(item.id);
      return item.id === parseInt(newStudent.id);
    });

    //   遍历对象
    for (var key in newStudent) {
      stu[key] = newStudent[key];
    }

    // 写入到dbPath中
    var fileData = JSON.stringify({
      students: students,
    });

    fs.writeFile(dbPath, fileData, function (error, data) {
      if (error) {
        return response.send("更改学生信息出错啦");
      }
      callback(null);
    });
  });
};

// 4.查找 id数据 函数
exports.findById = function (id, callback) {
  fs.readFile(dbPath, "utf8", function (error, data) {
    if (error) {
      return res.send("查找学生信息失败");
    }
    var students = JSON.parse(data).students;

    /*   
     find接受一个方法作为参数，方法内部返回一个条件
    find会遍历所有的元素，执行你给定的带有条件返回值的函数
    符合该条件的元素会作为find方法的返回值 */
    var ret = students.find(function (item) {
      // 只要 item.id  与 students.id 匹配  则返回其所有数据  封装成
      return item.id === parseInt(id);
    });
    callback(null, ret);
  });
};

// 5.删除 学生信息
exports.delete = function (id, callback) {
  fs.readFile(dbPath, "utf8", function (error, data) {
    if (error) {
      callback(error);
    }
    var students = JSON.parse(data).students;

    // findIndex  的作用是 根据条件查找元素下标
    //   findIndex  的目的  是为了拿到  需要删除的 索引值
    var del_Id = students.findIndex(function (item) {
      return item.id === parseInt(id);
    });

    //   根据获得的索引值，删除(splice)  对应学生的数据
    // 根据下标从数组中删除对应的学生对象  splice  第一个参数是起始位置(index),
    // 第二个参数是 删除个数
    students.splice(del_Id, 1);

    // 写入到dbPath中
    var fileData = JSON.stringify({
      students: students,
    });

    fs.writeFile(dbPath, fileData, function (error, data) {
      if (error) {
        return response.send("更改学生信息出错啦");
      }
      callback(null);
    });
  });
};
